package com.ruoyi.match.job.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.match.constant.CommonConstants;
import com.ruoyi.match.job.service.HistoryMatchTaskOddsChangeService;
import com.ruoyi.match.match.domain.HistoryMatchOddsChange;
import com.ruoyi.match.match.domain.Match;
import com.ruoyi.match.match.domain.RealTimeMatch;
import com.ruoyi.match.match.mapper.HistoryMatchOddsChangeMapper;
import com.ruoyi.match.match.mapper.MatchMapper;
import com.ruoyi.match.match.vo.MatchBaseInfo;
import com.ruoyi.match.match.vo.MatchOdds;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.math.BigDecimal;
import java.net.Proxy;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author sjz
 * @version 1.0.0
 * @desc
 * @date 2023/11/20 23:10
 **/

@Slf4j
@RequiredArgsConstructor
@Service
public class HistoryMatchTaskOddsChangeServiceImpl implements HistoryMatchTaskOddsChangeService {

    private final HistoryMatchOddsChangeMapper mapper;
    private final MatchMapper matchMapper;


    @Override
    public void getOddsChangeList(Match match, Proxy proxy) throws Exception {
        String matchUrl = String.format(CommonConstants.MATCH_ODDS_CHANGE_URL, match.getMatchFlag(),2);
        log.warn("查询路径{}",matchUrl);
        List<HistoryMatchOddsChange> changeList = Lists.newArrayList();
        String matchFlag = match.getMatchFlag();
        Connection connect = Jsoup.connect(matchUrl).proxy(proxy);
        Document document = connect.get();
        dataHandler(document,1,changeList,matchFlag);
        Thread.sleep(200);
        matchUrl = String.format(CommonConstants.MATCH_ODDS_CHANGE_URL, match.getMatchFlag(),14);
        connect = Jsoup.connect(matchUrl).proxy(proxy);
        document = connect.get();
        dataHandler(document,2,changeList,matchFlag);
        Thread.sleep(200);
        matchUrl = String.format(CommonConstants.MATCH_ODDS_CHANGE_URL, match.getMatchFlag(),82);
        connect = Jsoup.connect(matchUrl).proxy(proxy);
        document = connect.get();
        dataHandler(document,3,changeList,matchFlag);

        if(CollUtil.isNotEmpty(changeList)){
            mapper.delete(Wrappers.<HistoryMatchOddsChange>lambdaQuery().eq(HistoryMatchOddsChange::getMatchFlag,matchFlag));
            mapper.insertBatch(changeList);
        }
        if(StrUtil.isNotBlank(match.getMatchScore())){
            Map<Integer, List<HistoryMatchOddsChange>> changeMap = changeList.stream().collect(Collectors.groupingBy(HistoryMatchOddsChange::getType));
            MatchBaseInfo baseInfo = new MatchBaseInfo();
            // 竞彩赔率变化列表
            List<HistoryMatchOddsChange> jcChangeList = changeMap.containsKey(1) ? changeMap.get(1) : Lists.newArrayList();
            log.info("竞彩数量："+jcChangeList.size());
            oddsHandler(1,jcChangeList,baseInfo);
            // 威廉赔率变化列表
            List<HistoryMatchOddsChange> vlChangeList = changeMap.containsKey(2) ? changeMap.get(2) : Lists.newArrayList();
            log.info("威廉数量："+vlChangeList.size());
            if(CollUtil.isNotEmpty(vlChangeList)){
                oddsHandler(2,vlChangeList,baseInfo);
            }

            // 立博赔率变化列表
            List<HistoryMatchOddsChange> lbChangeList = changeMap.containsKey(3) ? changeMap.get(3) : Lists.newArrayList();
            log.info("立博数量："+vlChangeList.size());
            if(CollUtil.isNotEmpty(lbChangeList)){
                oddsHandler(3,lbChangeList,baseInfo);
            }
            List<MatchOdds> jcOdds = baseInfo.getJcOdds();
            if(CollUtil.isNotEmpty(jcOdds)){
                jcOdds.stream().filter(f-> Boolean.TRUE.equals(f.getInitFlag())).findFirst()
                    .ifPresent(i->{
                        match.setJcInitMain(i.getMainWinOdds());
                        match.setJcInitLevel(i.getLevelOdds());
                        match.setJcInitGust(i.getGustWinOdds());
                    });
            }
            List<MatchOdds> vlOdds = baseInfo.getVlOdds();
            if(CollUtil.isNotEmpty(vlOdds)){
                vlOdds.stream().filter(f-> Boolean.TRUE.equals(f.getInitFlag())).findFirst()
                    .ifPresent(i->{
                        match.setVlInitMain(i.getMainWinOdds());
                        match.setVlInitLevel(i.getLevelOdds());
                        match.setVlInitGust(i.getGustWinOdds());
                    });
                vlOdds.stream().filter(f-> Boolean.FALSE.equals(f.getInitFlag())).findFirst()
                    .ifPresent(i->{
                        match.setVlFinalMain(i.getMainWinOdds());
                        match.setVlFinalLevel(i.getLevelOdds());
                        match.setVlFinalGust(i.getGustWinOdds());
                    });
            }

            List<MatchOdds> lbOdds = baseInfo.getLbOdds();
            if(CollUtil.isNotEmpty(lbOdds)){
                lbOdds.stream().filter(f-> Boolean.TRUE.equals(f.getInitFlag())).findFirst()
                    .ifPresent(i->{
                        match.setLbInitMain(i.getMainWinOdds());
                        match.setLbInitLevel(i.getLevelOdds());
                        match.setLbInitGust(i.getGustWinOdds());
                    });
                lbOdds.stream().filter(f-> Boolean.FALSE.equals(f.getInitFlag())).findFirst()
                    .ifPresent(i->{
                        match.setLbFinalMain(i.getMainWinOdds());
                        match.setLbFinalLevel(i.getLevelOdds());
                        match.setLbFinalGust(i.getGustWinOdds());
                    });
            }
            String matchScore = match.getMatchScore();
            List<String> split = StrUtil.split(matchScore, ":");
            if(CollUtil.isNotEmpty(split) && split.size() == 2){
                int num = getJqResultByScore(split);
                int rqWin = getRqResultByScore(split,match.getRq());
                matchMapper.update(null, Wrappers.<Match>lambdaUpdate()
                    .set(Match::getJqNum,num)
                    .set(Match::getRqResult,rqWin)
                    .set(Match::getRemark,"1")
                    .set(Match::getJcInitMain,match.getJcInitMain())
                    .set(Match::getJcInitLevel,match.getJcInitLevel())
                    .set(Match::getJcInitGust,match.getJcInitGust())
                    .set(Match::getVlInitMain,match.getVlInitMain())
                    .set(Match::getVlInitLevel,match.getVlInitLevel())
                    .set(Match::getVlInitGust,match.getVlInitGust())
                    .set(Match::getVlFinalMain,match.getVlFinalMain())
                    .set(Match::getVlFinalLevel,match.getVlFinalLevel())
                    .set(Match::getVlFinalGust,match.getVlFinalGust())
                    .set(Match::getLbInitMain,match.getLbInitMain())
                    .set(Match::getLbInitLevel,match.getLbInitLevel())
                    .set(Match::getLbInitGust,match.getLbInitGust())
                    .set(Match::getLbFinalMain,match.getLbFinalMain())
                    .set(Match::getLbFinalLevel,match.getLbFinalLevel())
                    .set(Match::getLbFinalGust,match.getLbFinalGust())
                    .eq(Match::getId,match.getId()));
            }

        }

    }

    @Override
    public void getRealMatchOddsChangeList(RealTimeMatch match, Proxy proxy) throws InterruptedException, IOException {
        String matchUrl = String.format(CommonConstants.MATCH_ODDS_CHANGE_URL, match.getMatchFlag(),2);
        log.warn("查询路径{}",matchUrl);
        List<HistoryMatchOddsChange> changeList = Lists.newArrayList();
        String matchFlag = match.getMatchFlag();
        Connection connect = Jsoup.connect(matchUrl).proxy(proxy);
        Document document = connect.get();
        dataHandler(document,1,changeList,matchFlag);
        Thread.sleep(200);
        matchUrl = String.format(CommonConstants.MATCH_ODDS_CHANGE_URL, match.getMatchFlag(),14);
        connect = Jsoup.connect(matchUrl).proxy(proxy);
        document = connect.get();
        dataHandler(document,2,changeList,matchFlag);
        Thread.sleep(200);
        matchUrl = String.format(CommonConstants.MATCH_ODDS_CHANGE_URL, match.getMatchFlag(),82);
        connect = Jsoup.connect(matchUrl).proxy(proxy);
        document = connect.get();
        dataHandler(document,3,changeList,matchFlag);

        if(CollUtil.isNotEmpty(changeList)){
            mapper.delete(Wrappers.<HistoryMatchOddsChange>lambdaQuery().eq(HistoryMatchOddsChange::getMatchFlag,matchFlag));
            mapper.insertBatch(changeList);
        }
    }


    private void oddsHandler(int type, List<HistoryMatchOddsChange> changeList, MatchBaseInfo baseInfo) {
        if(CollUtil.isNotEmpty(changeList)){
            changeList = changeList.stream().sorted(Comparator.comparing(HistoryMatchOddsChange::getTimeAttr)).collect(Collectors.toList());
            HistoryMatchOddsChange first = CollUtil.getFirst(changeList);

            List<MatchOdds> odds = Lists.newArrayList();
            MatchOdds odd= new MatchOdds();
            odd.setMainWinOdds(first.getMainWinOdds());
            odd.setLevelOdds(first.getLevelOdds());
            odd.setGustWinOdds(first.getGustWinOdds());
            odd.setTimeAttr(first.getTimeAttr());
            odd.setTimeText(first.getTimeText());
            odd.setInitFlag(Boolean.TRUE);
            odds.add(odd);
            HistoryMatchOddsChange last = null;
            if (type != 1) {
                List<MatchOdds> jcOdds = baseInfo.getJcOdds();
                MatchOdds last1 = CollUtil.getLast(jcOdds);
                List<HistoryMatchOddsChange> changeList1 = changeList.stream().filter(f -> {
                    String timeAttr = "2023-" + last1.getTimeAttr() + ":00";
                    String timeAttr1 = "2023-" + f.getTimeAttr() + ":00";
                    LocalDateTime start = LocalDateTime.parse(timeAttr, DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN));
                    LocalDateTime end = LocalDateTime.parse(timeAttr1, DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN));
                    return !end.isAfter(start);
                }).collect(Collectors.toList());
                if(CollUtil.isNotEmpty(changeList1)){
                    changeList = changeList1;
                }
            }
            last = CollUtil.getLast(changeList);
            odd= new MatchOdds();
            odd.setMainWinOdds(last.getMainWinOdds());
            odd.setLevelOdds(last.getLevelOdds());
            odd.setGustWinOdds(last.getGustWinOdds());
            odd.setTimeAttr(last.getTimeAttr());
            odd.setTimeText(last.getTimeText());
            odd.setInitFlag(Boolean.FALSE);
            odds.add(odd);
            if(type == 1){
                baseInfo.setJcOdds(odds);
            }else if(type == 2){
                baseInfo.setVlOdds(odds);
            }else {
                baseInfo.setLbOdds(odds);
            }
        }
    }

    private void dataHandler(Document document,int companyType, List<HistoryMatchOddsChange> changeList,String matchFlag) {
        Element table = document.selectFirst("#scroller .changeTable");
        Elements trList = table.getElementsByTag("tr");
        for (Element tr : trList) {
            Elements tdList = tr.getElementsByTag("td");
            Element td1 = tdList.get(0);
            Elements spanList = td1.getElementsByTag("span");
            String main = spanList.get(0).text().trim();
            String level = spanList.get(1).text().trim();
            String gust = spanList.get(2).text().trim();
            System.out.printf("main:%s,level:%s,gust:%s%n",main,level,gust);
            Element td2 = tdList.get(1);
            String timeAttribute = td2.attr("time").trim();
            System.out.println("timeAttribute:"+timeAttribute);
            String timeText = td2.text().trim();
            System.out.println("timeText:"+timeText);
            HistoryMatchOddsChange oddsChange = new HistoryMatchOddsChange();
            oddsChange.setType(companyType);
            oddsChange.setMatchFlag(matchFlag);
            oddsChange.setMainWinOdds(new BigDecimal(main));
            oddsChange.setLevelOdds(new BigDecimal(level));
            oddsChange.setGustWinOdds(new BigDecimal(gust));
            oddsChange.setTimeAttr(timeAttribute);
            oddsChange.setTimeText(timeText);
            changeList.add(oddsChange);
        }
    }
    private int getRqResultByScore(List<String> split,String rq) {
        BigDecimal rqBig = new BigDecimal(rq);
        BigDecimal mainNum = new BigDecimal(split.get(0));
        BigDecimal gustNum = new BigDecimal(split.get(1));
        BigDecimal rqNum = mainNum.add(rqBig);
        if(rqNum.compareTo(gustNum) == 0){
            return 1;
        }else if(rqNum.compareTo(gustNum) > 0){
            return 3;
        }else {
            return 0;
        }
    }

    private Integer getJqResultByScore(List<String> split) {
        Integer a = Integer.valueOf(split.get(0));
        Integer b = Integer.valueOf(split.get(1));
        return a+b;
    }
}
